#ifdef SU1
#define _GLIBCXX_DEBUG
#endif

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define forl(i, n) for (int i = 1; i <= int(n); i++)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define fore(i, l, r) for (int i = int(l); i <= int(r); i++)
#define pb(a) push_back(a)
#define mp(x, y) make_pair((x), (y))
#define sz(a) (int) (a).size()
#define all(a) (a).begin(), (a).end()
#define ft first
#define sc second
#define x first
#define y second

template<typename X> inline X abs(const X& a) { return a < 0 ? -a : a; }
template<typename X> inline X sqr(const X& a) { return a * a; }

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

const int INF = int(1e9);
const li INF64 = li(1e18);
const ld PI = acosl(ld(-1));
const ld EPS = 1e-9;

const int N = 100 + 13;

struct edge
{
	int to, f, c, rev;
};

int n;
vector<int> initg[N];
int din[N], dout[N];
vector<edge> g[N];

void add (int from, int to, int cap)
{
	edge f = { to, 0, cap, sz(g[to]) };
	edge b = { from, 0, 0, sz(g[from]) };
	g[from].pb(f);
	g[to].pb(b);
}

inline bool read()
{
	if (scanf("%d", &n) != 1) return false;
	forn(i, n)
	{
		int cnt;
		assert(scanf("%d", &cnt) == 1);
		forn(j, cnt)
		{
			int to;
			assert(scanf("%d", &to) == 1);
			--to;
			initg[i].pb(to);
			add(i, to, INF);
			din[to]++;
			dout[i]++;
		}
	}
	return true;
}

int q[N], tail, head, d[N], mf[N], p[N], pe[N];

bool enlarge (int s, int t)
{
	forn(i, t + 1) d[i] = INF;
	d[s] = 0;
	
	tail = head = 0;
	q[tail++] = s;
	
	mf[s] = INF;
	
	while (tail != head)
	{
		int v = q[head++];
		
		forn(i, sz(g[v]))
		{
			const edge& e = g[v][i];
			if (e.f == e.c || d[e.to] <= d[v] + 1) continue;
			d[e.to] = d[v] + 1;
			p[e.to] = v;
			pe[e.to] = i;
			mf[e.to] = min(mf[v], e.c - e.f);
			q[tail++] = e.to;
		}
	}
	
	if (d[t] > INF / 2) return false;
	
	for (int v = t; v != s; v = p[v])
	{
		edge& e = g[p[v]][pe[v]];
		e.f += mf[t];
		g[v][e.rev].f -= mf[t];
	}
	
	return true;
}

inline bool can (int mid, int s, int t, int ss, int tt)
{
	forn(i, tt + 1) forn(j, sz(g[i])) g[i][j].f = 0;
	assert(g[t].back().to == s);
	g[t].back().c = mid;
	
	while (enlarge(ss, tt));
	
	forn(i, sz(g[ss])) if (g[ss][i].f < g[ss][i].c) return false;
	return true;
}

vector<int> way;

void fleury (int v)
{
	while (!initg[v].empty())
	{
		int to = initg[v].back();
		initg[v].pop_back();
		fleury(to);
	}
	way.pb(v);
}

vector<vector<int> > ans;

inline void solve()
{
	int s = n, t = s + 1, ss = t + 1, tt = ss + 1;
	forn(i, n)
	{
		if (din[i] == 0) add(s, i, INF);
		else add(ss, i, din[i]);
		
		if (dout[i] == 0) add(i, t, INF);
		else add(i, tt, dout[i]);
	}
	
	add(t, s, INF);
	
	int lf = 0, rg = INF;
	while (lf != rg)
	{
		int mid = (lf + rg) >> 1;
		if (can(mid, s, t, ss, tt))
			rg = mid;
		else
			lf = mid + 1;
	}
	
	assert(can(lf, s, t, ss, tt));
	
	forn(i, t + 1)
	{
		forn(j, sz(g[i]))
		{
			const edge& e = g[i][j];
			if (i == ss || e.to == tt) continue;
			forn(k, e.f) initg[i].pb(e.to);
		}
	}
	
	forn(i, t + 1) din[i] = dout[i] = 0;
	forn(i, t + 1) forn(j, sz(initg[i])) din[initg[i][j]]++, dout[i]++;
	forn(i, t + 1) assert(din[i] == dout[i]);
	
	fleury(s);
	reverse(all(way));
	
	//forn(i, sz(way)) cerr << way[i] + 1 << ' '; cerr << endl;
	
	assert(way[0] >= n && way.back() >= n);
	
	for (int i = 0; i < sz(way); i++)
	{
		if (way[i] >= n) continue;
		vector<int> cur;
		while (i < sz(way) && way[i] < n) cur.pb(way[i++]);
		ans.pb(cur);
	}
	
	cout << sz(ans) << endl;
	forn(i, sz(ans))
	{
		forn(j, sz(ans[i]))
		{
			if (j) putchar(' ');
			printf("%d", ans[i][j] + 1);
		}
		puts("");
	}
}

int main()
{
#ifdef SU1
	assert(freopen("input.txt", "rt", stdin));
//	assert(freopen("output.txt", "wt", stdout));
#endif

	cout << fixed << setprecision(10);
	cerr << fixed << setprecision(5);

	assert(read());
	solve();
	
#ifdef SU1
	cerr << "=== TIME : " << clock() << " ===" << endl;
#endif
	return 0;
}
